var ENGINE_ESTATE = {
    STATE_NONE: 0x0000,     //无状态
    STATE_HAVE_INIT: 0x0001,     //初始化
    STATE_HAVE_LOGIN: 0x0004,     //登录
    STATE_IN_ROOM: 0x0008     //在房间内
};

function UmspMsgReceiver(_engine) {
    var self = this;
    var engine = _engine;
    this.onMsg = function (dataView) {
        try {
            var packet = engine.mProtocol.decode(dataView);
            if (packet && packet.header) {
                // log.i("[Receive] cmd:" + CmdToString(packet.header.cmd) + " size:" + packet.header.size);
                if (self[packet.header.cmd]) {
                    self[packet.header.cmd](packet);
                } else {
                    console.warn("No Handler to handle cmd:" + CmdToString(packet.header.cmd));
                }

            } else {
                console.error("packet unpack fail dataView:" + dataView);
            }
        } catch (e) {
            log.e(e);
        }
    };
}


function UmspClient() {

    this.mProtocol = new UmspProtocol();
    this.mRoomID = 0;
    this.mUserID = 0;
    this.mGameID = 0;
    this.mGateWayNetWork = null;
    this.mRoomNetWork = null;
    var gateWayMsgReceiver;
    var roomServerMsgReceiver;
    /**
     * 登录
     * @userID {uint32} value 用户ID
     * @token {uint64} value 用户的token值
     * @gameID {uint32} gameID 游戏ID
     * @cb   {func} onSuccess(data),onErr(errCode,errInfo) }
     * @gateWayNetWorkListener   {func} onSuccess(data),onErr(errCode,errInfo) }
     * @envir {uint16} localhost/Dev/FlutterGo/Erdange
     */
    this.login = function (userID, token, gameID, cb, gateWayNetWorkListener, envir) {
        this.disConnect();
        this.mConfig = getHostConfig(envir);
        gateWayMsgReceiver = new UmspMsgReceiver(this);
        log.i("login to " + JSON.stringify(this.mConfig));
        // if(this.mGateWayNetWork!==null){
        //     this.mGateWayNetWork.close();
        // }
        gateWayMsgReceiver[Umsp.LOGIN_RSP] = cb;
        gateWayMsgReceiver[Umsp.HEARTBEAT] = function () {
            log.i("[Rsp][GateWayHeartBeat]");
        };
        //在连接建立时,增加心跳定时器
        this.heartBeatGateWay = this.heartBeatGateWay.bind(this);
        var gateWayTimer;
        var engine = this;
        gateWayMsgReceiver.onConnect = function (host) {
            gateWayTimer = setInterval(engine.heartBeatGateWay, HEART_BEAT_INTERVAL);
            gateWayNetWorkListener && gateWayNetWorkListener.onConnect && gateWayNetWorkListener.onConnect(host);
        };
        gateWayMsgReceiver.onErr = function (errCode, errMsg, host) {
            gateWayNetWorkListener && gateWayNetWorkListener.onErr && gateWayNetWorkListener.onErr(errCode, errMsg, host);
        };

        gateWayMsgReceiver.onDisConnect = function (errCode, errMsg, host) {
            clearInterval(gateWayTimer);
            log.i("remove the gateWayTimer:" + gateWayTimer);
            gateWayNetWorkListener && gateWayNetWorkListener.onDisConnect && gateWayNetWorkListener.onDisConnect(errCode, errMsg, host);
        };

        // noinspection JSCheckFunctionSignatures
        this.mGateWayNetWork = new WebSocketClient(this.mConfig.HOST_GATWAY_ADDR, gateWayMsgReceiver);
        this.mUserID = userID;
        this.mGameID = gameID;
        this.mGateWayNetWork.send(this.mProtocol.encode(Umsp.LOGIN, this.mUserID, token, this.mGameID));
    };


    this.match = function (matchResultListener, roomUserChangedListener, roomServiceNetWorkListener, roomMsgListener, match) {


        gateWayMsgReceiver[Umsp.MATCH_RSP] = function (rsp) {
            matchResultListener(rsp);
            var matchResult = JSON.parse(utf8ByteArrayToString(rsp.payload));
            if (matchResult["isSuccess"] === true) {
                log.i("match is success , the next step is  enter the room");

                var room = matchResult["room"];
                var url = room["roomURL"] ? ("ws://" + room["roomURL"]) : ("ws://" + room["roomIP"] + ":" + room["roomPort"]);
                roomServerMsgReceiver = new UmspMsgReceiver(this);
                roomServerMsgReceiver[Umsp.ROOM_USER_CHANGED] = roomUserChangedListener;
                roomServerMsgReceiver[Umsp.HEARTBEAT] = function () {
                    log.i("[Rsp][RoomServiceHeartBeat]");
                };


                //在连接建立时,增加心跳定时器
                this.heartBeatRoomService = this.heartBeatRoomService.bind(this);
                var timer;
                var engine = this;
                roomServerMsgReceiver.onConnect = function (host) {
                    timer = setInterval(engine.heartBeatRoomService, HEART_BEAT_INTERVAL);
                    roomServiceNetWorkListener && roomServiceNetWorkListener.onConnect && roomServiceNetWorkListener.onConnect(host);
                };
                roomServerMsgReceiver.onErr = function (errCode, errMsg, host) {
                    roomServiceNetWorkListener && roomServiceNetWorkListener.onErr && roomServiceNetWorkListener.onErr(errCode, errMsg, host);
                };

                roomServerMsgReceiver.onDisConnect = function (errCode, errMsg, host) {
                    clearInterval(timer);
                    log.i("onDisConnect,remove the timer:" + timer);
                    roomServiceNetWorkListener && roomServiceNetWorkListener.onDisConnect && roomServiceNetWorkListener.onDisConnect(errCode, errMsg, host);
                };
                roomServerMsgReceiver[Umsp.MSG_RSP] = function (rsp) {
                    roomMsgListener && roomMsgListener(utf8ByteArrayToString(rsp.payload));
                };
                this.mRoomNetWork = new WebSocketClient(url, roomServerMsgReceiver);
                this.mRoomID = matchResult["room"]["roomID"];
                var roomSession = matchResult["room"]["session"];
                this.mProtocol.setRoomID(this.mRoomID);
                return this.mRoomNetWork.send(
                    this.mProtocol.encode(
                        Umsp.ROOM_ENTER, "" + roomSession));
            } else {
                log.e("match fail");
            }


        }.bind(this);
        return this.mGateWayNetWork.send(
            this.mProtocol.encode(
                Umsp.MATCH, match || new Match(Match.prototype.RANDOM)
            )
        );
    };
    this.heartBeatGateWay = function () {
        this.mGateWayNetWork.send(this.mProtocol.encode(Umsp.HEARTBEAT));
    };
    this.heartBeatRoomService = function () {
        this.mRoomNetWork.send(this.mProtocol.encode(Umsp.HEARTBEAT));
    };
    this.getVersion = function () {
        return "Umsp-SDK-JS_v0.0.2.20180713";
    };
    this.disConnect = function () {
        log.i("Want to  close the connection");
        this.mGateWayNetWork && this.mGateWayNetWork.close();
        this.mRoomNetWork && this.mRoomNetWork.close();
    };
    this.broadcast = function (data) {
        if (typeof data != 'string') {
            data = JSON.stringify(data);
        }
        this.mRoomNetWork.send(this.mProtocol.encode(Umsp.MSG, data));
    };
}
